<?php

/**
 * Tworzy token
 *
 * @category   Core
 * @package    Core_Filter
 * @copyright  Copyright (c) 2008 Kuśmierz Adam
 * @author Adam Kuśmierz
 */

class Core_Filter_Token implements Zend_Filter_Interface
{
	/**
	 * Seed for token
	 * @var string
	 */
	protected $_seed = ''; // @TODO default hardcoded, change it in Validate_Token too!

	/**
	 * Constructor
	 *
	 * @param  string $seed
	 * @return void
	 */
	public function __construct($seed = null)
	{
		if (!empty($seed) && is_string($seed)) {
			$this->setSeed($seed);
		}
	}

	/**
	 * Sets seed to hash token
	 *
	 * @param string $seed
	 * @return Core_Filter_Preamble
	 */
	public function setSeed($seed)
	{
		$this->_seed = (string) $seed;
		
		return $this;
	}

	/**
	 * Returns seed
	 *
	 * @return string
	 */
	public function getSeed()
	{
		return $this->_seed;
	}
	
	/**
	 * Perform token filter
	 *
	 * @param string $text
	 * @return string
	 */
	public function filter($text)
	{
		list($microtime, $time) = explode(' ', microtime(false));
		$timeModulus = 33554432; // 2^25
		
		$microtime *= 128;
		$timeCongruent = $time % $timeModulus;
		
		$time = (intval(round($microtime)) << 25) + $timeCongruent;
		$timeSigned = unpack('l', pack('L', $time));
		$timeSigned = reset($timeSigned);
		$hash = md5(md5($text . $this->getSeed()) . abs($timeSigned));
		
		$H1 = hexdec(substr($hash, 0, 8));
		$H2 = substr($hash, 8);
		
		$token = array();
		for ($i = 0; $i < 8; ++ $i) {
			$token[] = dechex(($H1 & 0x3) + ($time & 0xc));
			$token[] = dechex(($H1 & 0xc) + ($time & 0x3));
			
			$H1 >>= 4;
			$time >>= 4;
		}
		
		$token = implode('', array_reverse($token)) . $H2;
		
		return $token;
	}
}